﻿#include "ZTimerSW.h"

#include <stdexcept>

#include "xil_printf.h"
#include "xtime_l.h"

ZTimerSW::ZTimerSW() {
  this->initialize();
}

void ZTimerSW::add(Task task) {
  TaskInternal taskInternal{};
  taskInternal.name = task.name;
  taskInternal.callback = task.callback;
  taskInternal.period = task.period;
  callbacks_[task.name] = taskInternal;
}

void ZTimerSW::remove(const std::string &taskName) {
  callbacks_.erase(taskName);
}

void ZTimerSW::runOnce() {
  // 查看当前的时间,如果过去了至少1ms,则执行一次逻辑
  unsigned tempTime = this->curTime();
  if (tempTime <= lastTime_) {
    // 时间没有变化,不执行逻辑
    return;
  }
  // 计算时差
  auto deltaTime = tempTime - lastTime_;
  // 更新上一次的时间
  lastTime_ = tempTime;

  // 遍历当前的回调函数,如果过去的时间大于等于周期,则执行回调函数
  for (auto &callback : callbacks_) {
    // 获得任务
    auto &task = callback.second;
    if (task.elapsedTime >= task.period) {
      if (task.callback) {
        // 执行回调函数
        task.callback();
      }
      // 重置过去的时间
      task.elapsedTime = 0;
    } else {
      // 增加过去的时间
      task.elapsedTime += deltaTime;
    }
  }
}

unsigned ZTimerSW::curTime() {
  XTime tempTime{};
  XTime_GetTime(&tempTime);
  return tempTime * 1000.0 / COUNTS_PER_SECOND;
}

void ZTimerSW::initialize() {
  // 获得当前的时间
  lastTime_ = curTime();
}
